<?php
/**
 * Created by PhpStorm.
 * User: zkc
 * Date: 2017-09-07
 * Time: 17:13
 */

namespace common\utils\soap;


use common\utils\TimeUtils;
use Exception;
use SoapFault;
use yii\base\Component;
use yii\base\ErrorException;

/**
 * Class SoapClient
 * 参考\mongosoft\soapclient\Client
 *
 * @package common\utils
 */
class SoapClientBak extends Component
{

    /**
     * @var string $url the URL of the WSDL file.
     */
    public $url;
    /**
     * @var array the array of SOAP client options.
     */
    public $options = [
    ];

    /**
     * @var \SoapClient the SOAP client instance.
     */
    private $_client;

    /**
     * @inheritdoc
     */
    public function init()
    {
        parent::init();
        if ($this->url === null) {
            throw new Exception('The "url" property must be set.');
        }

        // 必须开启此选项，才能获取发送接收的xml数据
        $this->options['trace']      = 1;
        $this->options['exception']  = 1;
        $this->options['user_agent'] = 'SoapClient';
        // 非生产环境不缓存wsdl
        if (!isset($this->options['cache_wsdl']) && (YII_DEBUG || !YII_ENV_PROD)) {
            $this->options['cache_wsdl'] = WSDL_CACHE_NONE;
        }

        try {
            $this->_client = new \SoapClient($this->url, $this->options);
        } catch (SoapFault $e) {
            throw new Exception($e->getMessage(), (int)$e->getCode(), $e);
        }
    }


    /**
     * @param string $name
     * @param array  $arguments
     *
     * @return mixed
     * @throws Exception
     */
    public function __call($name, $arguments)
    {
        $ret = null;
        $exp = null;

        // 记录日志
        $log_data = [];

        $log_data['@timestamp'] = TimeUtils::ESDateTime($_SERVER['REQUEST_TIME_FLOAT'], 3);;

        $log_data['reqid'] = $_SERVER['REQ_ID'];
        $log_data['env']   = YII_ENV;

        $log_data['url']    = $this->url;
        $log_data['method'] = $name;
        $log_data['args']   = json_encode($arguments, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);;

        try {
            $ret = call_user_func_array([$this->_client, $name], $arguments);
        } catch (Exception $e) {
            $exp = new Exception($e->getMessage(), (int)$e->getCode(), $e);
        }

        $log_data['usetime'] = sprintf("%.3f", microtime(true) - $_SERVER['REQUEST_TIME_FLOAT']);

        $log_data['request']          = $this->_client->__getLastRequest();
        $log_data['request.headers']  = $this->_client->__getLastRequestHeaders();
        $log_data['response']         = $this->_client->__getLastResponse();
        $log_data['response.headers'] = $this->_client->__getLastResponseHeaders();

        $log_data['code']   = '200';
        $log_data['return'] = json_encode($ret, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);

        if ($exp) {
            $log_data['code'] = '500';

            if ($exp instanceof ErrorException) {
                $message = "{$exp->getName()}";
            } elseif ($exp instanceof \yii\base\Exception) {
                $message = "Exception ({$exp->getName()})";
            } else {
                $message = 'Exception';
            }
            $message .= " '" . get_class($exp) . "' with message '{$exp->getMessage()}' \n\nin "
                . $exp->getFile() . ':' . $exp->getLine() . "\n\n"
                . "Stack trace:\n" . $exp->getTraceAsString();

            $log_data['exception.code']        = $exp->getCode();
            $log_data['exception.message']     = $exp->getMessage();
            $log_data['exception.file']        = $exp->getFile();
            $log_data['exception.line']        = $exp->getLine();
            $log_data['exception.stackstrace'] = $message;
        }

        \Yii::$app->es->post(['baoxian-' . date('Y.m.d'), 'soap-log'], [],
            json_encode($log_data, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES));

        if ($exp) {
            throw $exp;
        }

        return $ret;

    }
}